
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BPainter>
#include <BFileDialog>
#include <BReadWrite>

#include "MainWindow.h"

MainWindow::MainWindow()
{
	_waveItem = 0;
	_configDialog = new ConfigDialog(this);

	BWidget* leftWidget = new BWidget();
	{
		BHBoxLayout* buttonLayout = new BHBoxLayout();
		buttonLayout->setSizePolicy(Policy_Expanding, Policy_Preferred);
		{
			_openButton = new BButton("open");
			_saveButton = new BButton("save");
			_recordButton = new BButton("record");
			_recordButton->setCheckable(true);
			_deleteButton = new BButton("delete");

			buttonLayout->addWidget(_openButton);
			buttonLayout->addWidget(_saveButton);
			buttonLayout->addWidget(_recordButton);
			buttonLayout->addWidget(_deleteButton);
		}

		_waveListWidget = new BListWidget();

		BVBoxLayout* vlayout = new BVBoxLayout(leftWidget);
		vlayout->addLayout(buttonLayout);
		vlayout->addWidget(_waveListWidget);
	}

	BWidget* rightWidget = new BWidget();
	{
		_waveViewer = new WaveViewer(this);

		BHBoxLayout* buttonLayout = new BHBoxLayout();
		buttonLayout->setHeightPolicy(Policy_Preferred);
		{
			_playButton = new BButton("play");
			_playButton->setCheckable(true);
			_stopButton = new BButton("stop");
			_configButton = new BButton("config");

			buttonLayout->addSpring(10);
			buttonLayout->addWidget(_playButton);
			buttonLayout->addSpring(1);
			buttonLayout->addWidget(_stopButton);
			buttonLayout->addSpring(10);
			buttonLayout->addWidget(_configButton);
		}

		_output = new BTextEdit(this);
		_output->setBorder(5);
		_output->setMargin(5);

		BVBoxLayout* layout = new BVBoxLayout(rightWidget);
		layout->addWidget(_waveViewer);
		layout->addLayout(buttonLayout);
		layout->addWidget(_output);
	}

	BHBoxLayout* splitter = new BHBoxLayout();
	splitter->addWidget(leftWidget);
	splitter->addWidget(rightWidget);

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(splitter);

	_audioInput = new BAudioInput();
	_audioInput->setSampleRate(44100);
	_audioInput->setFormat(Format_UShort);
	_audioInput->open();

	_audioOutput = new BAudioOutput();
	_audioOutput->open();

	connect(_openButton, Signal_Clicked, &MainWindow::slotOpen);
	connect(_saveButton, Signal_Clicked, &MainWindow::slotSave);
	connect(_recordButton, Signal_Clicked, &MainWindow::slotRecord);
	connect(_deleteButton, Signal_Clicked, &MainWindow::slotDelete);

	connect(_playButton, Signal_Clicked, &MainWindow::slotPlay);
	connect(_stopButton, Signal_Clicked, &MainWindow::slotStop);
	connect(_configButton, Signal_Clicked, &MainWindow::slotShowConfigDialog);

	connect(Signal_Input, &MainWindow::slotAudioInput);
	connect(Signal_Output, &MainWindow::slotAudioOutput);

	connect(_waveListWidget, Signal_ItemClicked, &MainWindow::slotWaveItemClicked);

	_configDialog->init(_audioInput, _audioOutput);
}
MainWindow::~MainWindow()
{
	_audioInput->close();
	_audioOutput->close();
}

void MainWindow::slotOpen(BObject* object, const BValue& value)
{
	BStringList fileNames = BFileDialog::OpenFiles(this, "Open Wave files");
	for (int i = 0; i < fileNames.size(); i++)
	{
		const BString& fileName = fileNames[i];
		BAudio* audio = ReadFile<BAudio>(fileName);
		BListItem* item = new BListItem(fileName.name());
		item->setAsset(audio);
		_waveListWidget->addItem(item);
	}
}
void MainWindow::slotSave(BObject* object, const BValue& value)
{

}
void MainWindow::slotRecord(BObject* object, const BValue& value)
{
	if(_audioInput->state() == BAudio::State_Started)
	{
		_audioInput->stop();
		const BAudio* audio = _waveItem->asset();
		BString text = _waveItem->text();
		text += audio->bytes()->size();
		_waveItem->setText(text);
		_waveViewer->setWave(audio);
	}
	else
	{
		BAudio* audio = new BAudio();
		audio->setFormat(_audioInput->format());
		audio->setChannelCount(_audioInput->channelCount());
		audio->setSampleRate(_audioInput->sampleRate());
		_waveItem = new BListItem("wave");
		_waveItem->setAsset(audio);
		_waveListWidget->addItem(_waveItem);
		_waveListWidget->clearSelection();
		_waveItem->setSelected(true);
		_audioInput->start();
	}
}
void MainWindow::slotDelete()
{

}

void MainWindow::slotPlay(BObject* object, const BValue& value)
{
	if (_waveItem)
	{
		const BAudio* audio = _waveItem->asset();
		_audioOutput->setFormat(audio->format());
		_audioOutput->setChannelCount(audio->channelCount());
		_audioOutput->setSampleRate(audio->sampleRate());
		_audioOutput->setBuffer(*audio->bytes());
		_audioOutput->start();
	}
}
void MainWindow::slotStop(BObject* object, const BValue& value)
{

}
void MainWindow::slotShowConfigDialog()
{
	_configDialog->popup();
}
void MainWindow::slotWaveItemClicked(BObject* object, const BValue& value)
{
	_waveItem = value;
	const BAudio* audio = _waveItem->asset();
	_waveViewer->setWave(audio);
}
void MainWindow::slotAudioInput(BObject* object, const BValue& value)
{
	const BByteArray& buffer = value;
	BAudio* audio = _waveItem->asset();
	BByteArray* bytes = audio->bytes();
	if (!bytes)
	{
		bytes = new BByteArray();
		audio->setBytes(bytes);
	}
	bytes->append(buffer);
	_waveViewer->fresh();
}
void MainWindow::slotAudioOutput(BObject* object, const BValue& value)
{
	_output->addText("\nplay over");
}
